package com.yale.elasticsearch.service.query;


import com.yale.elasticsearch.dto.TermQueryDTO;
import com.yale.elasticsearch.model.entity.UserInfo;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 精确查询
 */
@Service
@Slf4j
public class TermQueryService {

    @Resource
    private ElasticsearchClient elasticsearchClient;

    /**
     * 精确查询（查询条件不会进行分词，但是查询内容可能会分词，导致查询不到）
     */
    public Object termQuery(TermQueryDTO termQueryDTO) {
        Object result = "";
        try {
            // 构建 Term 查询条件
            Query termQuery = Query.of(q -> q
                    .term(t -> t
                            .field(termQueryDTO.getField())
                            .value(of -> of.stringValue(termQueryDTO.getValue()))
                    )
            );

            // 创建查询请求对象
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index(termQueryDTO.getIndexName())
                    .query(termQuery)
            );

            // 执行查询
            SearchResponse<JsonData> searchResponse = elasticsearchClient.search(searchRequest, JsonData.class);
            List<UserInfo> userInfoList = new ArrayList<>();
            // 处理响应结果
            if (searchResponse.hits().total().value() > 0) {
                searchResponse.hits().hits().forEach(hit -> {
                    // 将 JSON 转换成对象
                    UserInfo userInfo = JSON.parseObject(hit.source().toJson().toString(), UserInfo.class);
                    userInfoList.add(userInfo);
                    // 输出查询信息
                    log.info("打印查询结果：{}", JSON.toJSONString(userInfo));
                });
            }

            result = JSON.toJSONString(userInfoList);

        } catch (IOException e) {
            log.error("Error executing search request: {}" , e.getMessage());
        }
        return result;
    }


    /**
     * 多个内容在一个字段中进行查询
     */
    public Object termsQuery(TermQueryDTO termQueryDTO) {
        Object result = "";
        try {
            List<FieldValue> values = new ArrayList<>();
            if(termQueryDTO != null && termQueryDTO.getValues() != null && termQueryDTO.getValues().length > 0){
                for (int i = 0; i < termQueryDTO.getValues().length; i++){
                    values.add(FieldValue.of(termQueryDTO.getValues()[i]));
                }
            }

            // 构建 Terms 查询条件
            Query termsQuery = Query.of(q -> q
                    .terms(t -> t
                            .field(termQueryDTO.getField())
                                    .terms(v -> v.value(values))
                    )
            );

            // 创建查询请求对象
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index(termQueryDTO.getIndexName())
                    .query(termsQuery)
            );

            // 执行查询
            SearchResponse<JsonData> searchResponse = elasticsearchClient.search(searchRequest, JsonData.class);
            List<UserInfo> userInfoList = new ArrayList<>();
            // 处理响应结果
            if (searchResponse.hits().total().value() > 0) {
                searchResponse.hits().hits().forEach(hit -> {
                    // 将 JSON 转换成对象
                    UserInfo userInfo = JSON.parseObject(hit.source().toJson().toString(), UserInfo.class);
                    // 输出查询信息
                    log.info("打印查询结果：{}", JSON.toJSONString(userInfo));
                    userInfoList.add(userInfo);
                });
            }

            result = JSON.toJSONString(userInfoList);

        } catch (IOException e) {
            log.error("Error executing search request: {}" , e.getMessage());
        }
        return result;
    }


}